﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;
using VMExplorer.Forms;
using VMExplorer.MemoryObjects;

namespace VMExplorer.Controls
{
  partial class MemoryObjects : UserControl
  {
    private VMEDocument _doc;
    bool _bChangeSelectedPage;

    public MemoryObjects()
    {
      InitializeComponent();
      _doc = null;
      _bChangeSelectedPage = true;
    }

    public VMEDocument Document
    {
      get { return _doc; }
      set
      {
        if (_doc != null)
        {
          _doc.SelectedObjectChanged -= _doc_SelectedObjectChanged;
          _doc.DataUpdated -= _doc_DataUpdated;
        }
        _doc = value;
        if (_doc != null)
        {
          _doc.SelectedObjectChanged += _doc_SelectedObjectChanged;
          _doc.DataUpdated += _doc_DataUpdated;
        }
        UpdateList();
      }
    }

    void _doc_DataUpdated (object sender, EventArgs e)
    {
      Invoke((MethodInvoker)delegate() { 
        UpdateList ();
      });
    }

    void _doc_SelectedObjectChanged (object sender, SelectedObjectChangeEventArgs e)
    {
			Invoke ((MethodInvoker)delegate ()
			{
				_bChangeSelectedPage = false;

				if (e.Selection == null && listView1.SelectedItems.Count > 0)
				{
					listView1.SelectedItems [0].Selected = false;
				}
				else
				{
					foreach (ListViewItem lvi in listView1.Items)
					{
						if ((IMemoryObject)lvi.Tag == e.Selection)
						{
							lvi.Selected = true;
							break;
						}
					}
				}

				_bChangeSelectedPage = true;
			});
    }

    private void UpdateList ()
    {
      listView1.BeginUpdate ();

      try
      {
        listView1.Items.Clear ();

        if (_doc == null) return;

        List<IMemoryObject> mobj = _doc.MemoryObjects;

        foreach (IMemoryObject mo in mobj)
        {
          ListViewItem lvi = new ListViewItem (new string [] { mo.Name, mo.BaseAddress.ToString () });

          string groupName = mo.Type.ToString();
          switch (mo.Type)
          {
          case RegionUsage.Free:
          case RegionUsage.Undefined:
          case RegionUsage.VirtualAllocated:
              groupName = "Other";
              break;
          }

          lvi.Group = listView1.Groups[groupName];
          if (lvi.Group == null)
          {
            lvi.Group = new ListViewGroup(groupName, groupName);
            listView1.Groups.Add (lvi.Group);
          }
          lvi.Tag = mo;

          listView1.Items.Add (lvi);
        }
      }
      finally
      {
        listView1.EndUpdate ();
      }
    }

		void listView1_ItemActivate (object sender, EventArgs e)
		{
			//if (!_bChangeSelectedPage) return;

			//MemoryAddress ma = MemoryAddress.Invalid;

			//if (listView1.SelectedItems.Count > 0)
			//{
			//  IMemoryObject mo = (IMemoryObject)listView1.SelectedItems [0].Tag;
			//  ma = mo.BaseAddress;
			//}

			//_doc.SelectedAddress = ma;
		}

		private void listView1_SelectedIndexChanged (object sender, EventArgs e)
    {
			if (!_bChangeSelectedPage) return;

			MemoryAddress ma = MemoryAddress.Invalid;

			if (listView1.SelectedItems.Count > 0)
			{
				IMemoryObject mo = (IMemoryObject)listView1.SelectedItems [0].Tag;
				ma = mo.BaseAddress;

				_doc.SelectedAddress = ma;
			}
    }

		private void listView1_DoubleClick (object sender, EventArgs e)
		{
			if (listView1.SelectedItems.Count > 0)
			{
				(new PropertyForm ((IMemoryObject)listView1.SelectedItems [0].Tag)).Show ();
			}
		}
  }
}
